package com.ddh.ddhsanguogame.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ddh.ddhsanguogame.dto.CardUserRegisterDTO;
import com.ddh.ddhsanguogame.exception.DongException;
import com.ddh.ddhsanguogame.exception.ErrorCode;
import com.ddh.ddhsanguogame.service.IUserService;
import com.ddh.ddhsanguogame.entity.CardUser;
import com.ddh.ddhsanguogame.mapper.UserMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ddh.ddhsanguogame.utils.JwtUtil;
import com.ddh.ddhsanguogame.utils.PasswordUtil;
import com.ddh.ddhsanguogame.vo.CardUserLoginVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author
 * @since 2025-06-28
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, CardUser> implements IUserService {

    /**
     * 用户注册
     *
     * @param cardUserRegisterDTO
     * @return
     */
    @Transactional
    @Override
    public boolean register(CardUserRegisterDTO cardUserRegisterDTO) {
        // 1. 校验用户名是否已存在
        LambdaQueryWrapper<CardUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CardUser::getUsername, cardUserRegisterDTO.getUsername());
        if (this.count(queryWrapper) > 0) {
            throw new DongException(ErrorCode.USER_EXIST_ERROR);
        }
        // 2. 构建用户对象并加密密码
        //参数校验
        validateRegisterDTO(cardUserRegisterDTO);
        CardUser cardUser = new CardUser();
        cardUserRegisterDTO.setPassword(PasswordUtil.encode(cardUserRegisterDTO.getPassword()));
        BeanUtils.copyProperties(cardUserRegisterDTO, cardUser);
        // TODO: 文件上传后续实现,需要给一个默认头像
        cardUser.setAvatarUrl("");
        cardUser.setCreatedAt(LocalDateTime.now());
        cardUser.setCreatedBy(1L);
        // 3. 保存用户
        return this.save(cardUser);
    }

    /**
     * 用户登录
     *
     * @param cardUserRegisterDTO
     * @return
     */
    @Override
    public CardUserLoginVO login(CardUserRegisterDTO cardUserRegisterDTO) {
        // 1. 参数校验
        if (cardUserRegisterDTO.getUsername() == null || cardUserRegisterDTO.getUsername().trim().isEmpty()) {
            throw new DongException(ErrorCode.USERNAME_EMPTY_ERROR);
        }
        if (cardUserRegisterDTO.getPassword() == null || cardUserRegisterDTO.getPassword().trim().isEmpty()) {
            throw new DongException(ErrorCode.PASSWORD_EMPTY_ERROR);
        }

        // 2. 查询用户
        LambdaQueryWrapper<CardUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CardUser::getUsername, cardUserRegisterDTO.getUsername());
        CardUser cardUser = this.getOne(queryWrapper);

        if (cardUser == null) {
            throw new DongException(ErrorCode.USER_NOT_FOUND_ERROR);
        }

        // 3. 密码验证
        if (!PasswordUtil.matches(cardUserRegisterDTO.getPassword(), cardUser.getPassword())) {
            throw new DongException(ErrorCode.PASSWORD_ERROR);
        }

        // 4. 生成 Token
        String token = JwtUtil.generateToken(String.valueOf(cardUser.getId()), 1000 * 60 * 60 * 60); // 有效期为 1 天

        // 5. 构建并返回 UserVO
        CardUserLoginVO cardUserLoginVO = new CardUserLoginVO();
        BeanUtils.copyProperties(cardUser, cardUserLoginVO);
        cardUserLoginVO.setToken(token);

        return cardUserLoginVO;
    }

    @Override
    public CardUser getUserById(Long userId) {
        return getById(userId);
    }


    private void validateRegisterDTO(CardUserRegisterDTO cardUserRegisterDTO) {
        if (cardUserRegisterDTO.getUsername() == null || cardUserRegisterDTO.getUsername().trim().isEmpty()) {
            throw new DongException(ErrorCode.USERNAME_EMPTY_ERROR);
        }
        if (cardUserRegisterDTO.getPassword() == null || cardUserRegisterDTO.getPassword().trim().isEmpty()) {
            throw new DongException(ErrorCode.PASSWORD_EMPTY_ERROR);
        }
        if (cardUserRegisterDTO.getNickname() == null || cardUserRegisterDTO.getNickname().trim().isEmpty()) {
            throw new DongException(ErrorCode.NICKNAME_EMPTY_ERROR);
        }
    }


}
